package com.coderman.infosys.auth.app.executor;

import com.coderman.infosys.auth.app.command.AbstractCmd;

import com.coderman.infosys.auth.app.command.AddUserGroupCmd;
import com.coderman.infosys.auth.domain.bo.event.UserGroupCreatedEvent;
import com.coderman.infosys.auth.domain.bo.user.UserGroupBO;
import com.coderman.infosys.auth.domain.enums.errors.UserGroupErrorEnum;
import com.coderman.infosys.auth.domain.repository.UserRoleRepository;
import com.coderman.infosys.auth.domain.utils.AppEventPublisher;
import com.coderman.infosys.plat.auth.common.behavior.IAppOperation;
import com.coderman.infosys.plat.auth.common.dto.ResultDataDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.coderman.infosys.auth.app.executor.UserGroupCmdExe;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Description:用户组cmd处理类接口实现类
 * @Author：2022-01-02
 * @CreateTime：2022-01-02 15:27:38
 * @version v1.0
 */
@Service
public class UserGroupCmdExe  implements  CmdExeService{

	private  Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private AppEventPublisher appEventPublisher;

    @Override
    @Transactional(rollbackFor = Exception.class)
	public ResultDataDto exe(IAppOperation appOperation, AbstractCmd abstractCmd){
        AddUserGroupCmd addUserGroupCmd = (AddUserGroupCmd) abstractCmd;

        //1.判断是否满足用户数限制
        if(addUserGroupCmd.satisfyUserCount()){
            //由于加了事务了，这里抛出异常会更合适一些
            return ResultDataDto.fail(UserGroupErrorEnum.USER_COUNT_OVER_ERROR);
        }

        UserGroupBO userGroupBO = addUserGroupCmd.buildUserGroupBO(addUserGroupCmd.getCreateUserGroupRequestDTO());
        //2.准备持久化用户组信息
        userRoleRepository.registUserGroup(addUserGroupCmd.buildUserGroupBO(addUserGroupCmd.getCreateUserGroupRequestDTO()));
        //3.发送事务成功事件,由于这里是带有事务的消息并且是异步的事件，所以为了保证业务逻辑的顺序性和完整性,事务逻辑建议在应用层
        //参考eventHandler包
        appEventPublisher.publish(new UserGroupCreatedEvent(this,userGroupBO));
        return ResultDataDto.success();
    }

}